package com.lgl.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lgl.constants.SystemConstants;
import com.lgl.dto.ArticleDto;
import com.lgl.entity.ArticleTag;
import com.lgl.entity.Category;
import com.lgl.entity.ResponseResult;
import com.lgl.enums.AppHttpCodeEnum;
import com.lgl.exception.SystemException;
import com.lgl.mapper.ArticleMapper;
import com.lgl.entity.Article;
import com.lgl.mapper.ArticleTagMapper;
import com.lgl.mapper.TagMapper;
import com.lgl.service.ArticleService;
import com.lgl.service.ArticleTagService;
import com.lgl.service.CategoryService;
import com.lgl.service.TagService;
import com.lgl.utils.BeanCopyUtils;
import com.lgl.utils.RedisCache;
import com.lgl.utils.SecurityUtils;
import com.lgl.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@Slf4j
@Service
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, Article> implements ArticleService {
    @Lazy
    @Autowired
    private CategoryService categoryService;

    @Override
    public ResponseResult queryHotArticleList() {
//        是否为正式文章
        LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Article::getStatus, SystemConstants.ARTICLE_STATUS_NORMAL);
//        按照降序排序
        queryWrapper.orderByDesc(Article::getViewCount);
        Page<Article> page = new Page<>();
        page.setCurrent(1);
        page.setSize(10);
        List<Article> records = page(page, queryWrapper).getRecords();
        List articleList = new ArrayList<HotArticleVo>();
        for (Article article : records) {
            HotArticleVo hotArticleVo = new HotArticleVo();
            BeanUtils.copyProperties(article, hotArticleVo);
            articleList.add(hotArticleVo);
        }
        return ResponseResult.okResult(articleList);
    }

    @Override
    public ResponseResult articleList(Integer pageNum, Integer pageSize, Long categoryId) {
        //        查询文章为正式发布的 并判断有无分类id
        LambdaQueryWrapper<Article> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Objects.nonNull(categoryId) && categoryId > 0, Article::getCategoryId, categoryId);
        lambdaQueryWrapper.eq(Article::getStatus, SystemConstants.ARTICLE_STATUS_NORMAL);
        lambdaQueryWrapper.orderByDesc(Article::getIsTop);
        Page<Article> page = new Page<>();
        page.setSize(pageSize);
        page.setCurrent(pageNum);
        page(page, lambdaQueryWrapper);
//       封装并返回
        List<Article> list = page.getRecords();
        for (Article article : list) {
            Category category = categoryService.getById(article.getCategoryId());
            article.setCategoryName(category.getName());
        }

        List<ArticleListVo> articleListVos = BeanCopyUtils.copyBeanList(page.getRecords(), ArticleListVo.class);
        PageVo pageVo = new PageVo(articleListVos, page.getTotal());
        return ResponseResult.okResult(pageVo);

    }

    @Autowired
    private ArticleTagMapper articleTagMapper;

    @Override
    public ResponseResult getArticleDetail(Long id) {
        Article article = getById(id);
        Integer cacheMapValue = redisCache.getCacheMapValue("article:viewCount", id.toString());
        article.setViewCount(cacheMapValue.longValue());

            Category category = categoryService.getById(article.getCategoryId());
            if (category != null) {
                article.setCategoryName(category.getName());
            }
            ArticleDetailVo articleDetailVo = BeanCopyUtils.beanCopy(article, ArticleDetailVo.class);
            return ResponseResult.okResult(articleDetailVo);

//        List<Long> tags = articleTagMapper.getTagList(id);
//        AdminArticleDetailVo adminArticleDetailVo = BeanCopyUtils.beanCopy(article, AdminArticleDetailVo.class);
//        adminArticleDetailVo.setTags(tags);
//        return ResponseResult.okResult(adminArticleDetailVo);
    }

    @Autowired
    private RedisCache redisCache;

    @Override
    public ResponseResult updateViewCount(Long id) {
        redisCache.incrementCacheMapValue("article:viewCount", id.toString(), 1);
        return ResponseResult.okResult();
    }

    @Autowired
    private ArticleTagService articleTagService;

    @Override
    @Transactional
    public ResponseResult addArticle(ArticleDto articleDto) {
        if (!StringUtils.hasText(articleDto.getContent())
                ||CollectionUtils.isEmpty(articleDto.getTags())
                ||!StringUtils.hasText(articleDto.getTitle())
                ||articleDto.getCategoryId() == null
        ){
            throw new SystemException(AppHttpCodeEnum.ARTICLE_ERROR);
        }
        Article article = BeanCopyUtils.beanCopy(articleDto, Article.class);
        save(article);
        List<Long> tagIds = articleDto.getTags();
        List<ArticleTag> articleTags = new ArrayList<>();
        for (Long tag : tagIds) {
            ArticleTag articleTag = new ArticleTag(articleDto.getId(), tag);
            articleTags.add(articleTag);
        }
        articleTagService.saveBatch(articleTags);
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult getList(Integer pageSize, Integer pageNum, String title, String summary) {
        Page<Article> articlePage = new Page<>();
        articlePage.setCurrent(pageNum);
        articlePage.setSize(pageSize);
        LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.hasText(title), Article::getTitle, title);
        queryWrapper.like(StringUtils.hasText(summary), Article::getSummary, summary);
        queryWrapper.eq(Article::getStatus, SystemConstants.STATUS_NORMAL);
        Page<Article> page = page(articlePage, queryWrapper);
        List<Article> records = page.getRecords();
        List<GetArticleList> getArticleLists = BeanCopyUtils.copyBeanList(records, GetArticleList.class);
        PageVo pageVo = new PageVo(getArticleLists, page.getTotal());
        return ResponseResult.okResult(pageVo);
    }
    @Override
    @Transactional
    public ResponseResult updateArticle(AdminArticleDetailVo adminArticleDetailVo) {

        Article article = BeanCopyUtils.beanCopy(adminArticleDetailVo, Article.class);
//        redisCache.setCacheMapValue("article:viewCount", article.getId().toString(),article.getViewCount() );
        if (Objects.isNull(article)){
            throw new RuntimeException("更新的数据不能为空");
        }
        updateById(article);
        LambdaQueryWrapper<ArticleTag> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ArticleTag::getArticleId,adminArticleDetailVo.getId());
        articleTagService.remove(queryWrapper);
        List<ArticleTag> articleTags = new ArrayList<>();
        for (Long tag : adminArticleDetailVo.getTags()) {
                ArticleTag articleTag = new ArticleTag(adminArticleDetailVo.getId(),tag);
                articleTags.add(articleTag);
        }
        articleTagService.saveBatch(articleTags);
        return ResponseResult.okResult();
    }

    @Override
    @Transactional
    public ResponseResult deleteArticle(Long id) {
        removeById(id);
        LambdaQueryWrapper<ArticleTag> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ArticleTag::getArticleId,id);
        articleTagService.remove(queryWrapper);
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult getAdminArticleDetil(Long id) {
        Article article = getById(id);
        Integer cacheMapValue = redisCache.getCacheMapValue("article:viewCount", id.toString());
        article.setViewCount(cacheMapValue.longValue());

        Category category = categoryService.getById(article.getCategoryId());
        if (category != null) {
            article.setCategoryName(category.getName());
        }
        List<Long> tags = articleTagMapper.getTagList(id);
        AdminArticleDetailVo adminArticleDetailVo = BeanCopyUtils.beanCopy(article, AdminArticleDetailVo.class);
        adminArticleDetailVo.setTags(tags);
        return ResponseResult.okResult(adminArticleDetailVo);
    }


}

